﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Web;
using System.Web.Mvc;
using LiveProjectManager.DDD;


namespace LiveProjectManager.Controllers
{
    public class TaskController : Controller
    {
        private static DDD.Services.TaskService _service = new DDD.Services.TaskService();
        private static DDD.Services.UserService _userService = new DDD.Services.UserService();


        //
        // GET: /Task
        public ActionResult Index(int paginateBy = 0, int page = 1)
        {
            return Json(
                DDD.Services.TaskService.toDict(_service.getAll(paginateBy, page)),
                JsonRequestBehavior.AllowGet
            );
        }


        //
        // GET: /Task/IndexByAssignee/{assigneeId}
        public ActionResult IndexByAssignee(long userId, int paginateBy = 0, int page = 1)
        {
            DDD.Domains.User myUser = _userService.getById(userId);

            // Can't find a matching resource.
            if (myUser == null)
                return new HttpStatusCodeResult((int)HttpStatusCode.NotFound);

            return Json(
                DDD.Services.TaskService.toDict(_service.getAllByAssignee(myUser, paginateBy, page)),
                JsonRequestBehavior.AllowGet
            );
        }


        //
        // GET: /Task/Details/{Id}
        public ActionResult Details(long id)
        {
            DDD.Domains.Task myTask = _service.getById(id);

            // Can't find a matching resource.
            if (myTask == null)
                return new HttpStatusCodeResult((int)HttpStatusCode.NotFound);

            // Return formatted resource.
            return Json(myTask.toDict(), JsonRequestBehavior.AllowGet);
        }


        //
        // POST: /Task/Create
        [HttpPost]
        public ActionResult Create(FormCollection myFormData)
        {
            DDD.Domains.User myUser = _userService.getByUserName(myFormData["UserName"]);

            // Validate user.
            if (myUser == null)
                return new HttpStatusCodeResult((int)HttpStatusCode.BadRequest, "No User found with UserName: " + myFormData["UserName"] + ".");
            
            // Parse & validate priority; Parsse & validate progression.
            try
            {
                DDD.Domains.TaskPriority myPriority = (DDD.Domains.TaskPriority) Enum.Parse(
                    typeof(DDD.Domains.TaskPriority), 
                    myFormData["PriorityLabel"]
                );
                int myProgression = Int32.Parse(myFormData["Progression"]);

                if (!_service.create(myFormData["Title"], myUser, myProgression, myPriority, myFormData["Description"]))
                    return new HttpStatusCodeResult((int)HttpStatusCode.BadRequest, "Incorret or missing parameters.");
                return new HttpStatusCodeResult((int)HttpStatusCode.Created);
            }
            catch (ArgumentException)
            {
                return new HttpStatusCodeResult((int)HttpStatusCode.BadRequest, "Incorret priority label, allowed are: 'LOW', 'MEDIUM', 'HIGH', 'URGENT'");
            }
            catch (FormatException) 
            {
                return new HttpStatusCodeResult((int)HttpStatusCode.BadRequest, "Incorret progression value, allowed range is [0, 100] inclusive.");
            }
        }


        //
        // POST: /Task/Update
        [HttpPut]
        public ActionResult Update(FormCollection myFormData)
        {
            DDD.Domains.User myUser = _userService.getByUserName(myFormData["UserName"]);

            // Validate user.
            if (myUser == null)
                return new HttpStatusCodeResult((int)HttpStatusCode.BadRequest, "No User found with UserName: " + myFormData["UserName"] + ".");

            // Parse & validate priority; Parsse & validate progression.
            try
            {
                DDD.Domains.TaskPriority myPriority = (DDD.Domains.TaskPriority)Enum.Parse(
                    typeof(DDD.Domains.TaskPriority),
                    myFormData["PriorityLabel"]
                );
                int myId = Int32.Parse(myFormData["Id"]);
                int myProgression = Int32.Parse(myFormData["Progression"]);

                if (!_service.update(myId, myFormData["Title"], myUser, myProgression, myPriority, myFormData["Description"]))
                    return new HttpStatusCodeResult((int)HttpStatusCode.BadRequest, "Incorret or missing parameters.");
                return new HttpStatusCodeResult((int)HttpStatusCode.OK);
            }
            catch (ArgumentException)
            {
                return new HttpStatusCodeResult((int)HttpStatusCode.BadRequest, "Incorret priority label, allowed are: 'LOW', 'MEDIUM', 'HIGH', 'URGENT'");
            }
            catch (FormatException)
            {
                return new HttpStatusCodeResult((int)HttpStatusCode.BadRequest, "Incorret progression value, allowed range is [0, 100] inclusive.");
            }
        }


        //
        // DELETE: /Task/Delete
        [HttpDelete]
        public ActionResult Delete(FormCollection myFormCollection)
        {
            try
            {
                // Entity to delete is not found.
                if (!_service.exists(long.Parse(myFormCollection["Id"])))
                    return new HttpStatusCodeResult((int)HttpStatusCode.NotFound);

                // Unknown error occured, unable to delete.
                if (!_service.remove(long.Parse(myFormCollection["Id"])))
                    return new HttpStatusCodeResult((int)HttpStatusCode.InternalServerError);

                // Deletion successful
                return new HttpStatusCodeResult((int)HttpStatusCode.NoContent);
            }
            catch (Exception)
            {
                return new HttpStatusCodeResult((int)HttpStatusCode.BadRequest, "Invalid Id parameter (must be a long).");
            }
        }
    }
}